"""
Case Type   : 资源池化系统视图
Case Name   : 配置mes相关配置在较小值，构造failover场景，查看相关系统视图中DMSDrcContext的内存统计信息
Create At   : 2025/2
Owner       : haomeng
Description :
    1、查看mes相关配置默认值
    2、设置相关参数值为较小值
    3、主备节点分别查看系统视图pg_total_memory_detail中DMSDrcContext字段是否存在
    4、主备节点分别查看系统表gs_shared_memory_detail中DMSDrcContext字段是否存在
    5、主备节点分别查看系统表gs_thread_memory_context中DMSMemContext字段是否存在
    6、主备节点分别查看关联函数dbe_perf.track_memory_context_detail信息
    7、mv掉dn目录，kill掉dn进程,查看集群状态
    8、新主备节点分别查看系统视图pg_total_memory_detail中DMSDrcContext字段是否存在
    9、新主备节点分别查看系统表gs_shared_memory_detail中DMSDrcContext字段是否存在
    10、新主备节点分别查看系统表gs_thread_memory_context中DMSMemContext字段是否存在
    11、新主备节点分别查看关联函数dbe_perf.track_memory_context_detail信息
    12、恢复初始环境
Expect      :
    1、查看成功
    2、设置成功
    3、无相关信息
    4、存在DMSDrcContext相关字段及信息
    5、存在DMSMemContext相关字段及信息
    6、无相关信息
    7、原主异常，集群内产生新主
    8、无相关信息
    9、存在DMSDrcContext相关字段及信息
    10、存在DMSMemContext相关字段及信息
    11、无相关信息
    12、环境恢复成功
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class ShareStorageSystemView(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [CommonSH('PrimaryDbUser'), CommonSH('Standby1DbUser'), CommonSH('Standby2DbUser')]
        self.pri_user = Node(node='PrimaryDbUser')
        self.com = Common('PrimaryDbUser')
        self.constant = Constant()

        self.param1 = 'ss_interconnect_channel_count'
        self.param2 = 'ss_work_thread_count'
        self.param3 = 'ss_work_thread_pool_attr'
        self.param4 = 'ss_recv_msg_pool_size'

        self.sys_view1 = 'pg_total_memory_detail'
        self.sys_view2 = 'gs_total_memory_detail'
        self.sys_view3 = 'gs_shared_memory_detail'
        self.sys_view4 = 'pg_shared_memory_detail()'
        self.sys_view5 = 'gs_thread_memory_context'
        self.sys_view6 = 'gs_session_memory_detail'
        self.sys_view7 = 'gs_get_thread_memctx_detail'
        self.sys_view8 = 'dbe_perf.track_memory_context'
        self.sys_view9 = 'dbe_perf.track_memory_context_detail()'

    def test_ss_system_view(self):
        text = '-----step1:查看mes相关配置默认值  expect:查看成功-----'
        self.log.info(text)

        self.param_list = [self.param1, self.param2, self.param3, self.param4]
        value_list = ['1', '16', "''", '32MB']

        self.default_value = []
        for param in self.param_list:
            value = self.user_node[0].execut_db_sql(f'show {param}')
            tmp = value.splitlines()[-2].strip() if value.splitlines()[-2].strip() else "''"
            self.default_value.append(tmp)
        self.log.info(self.default_value)

        text = '-----step2:设置相关参数值为较小值  expect:设置成功-----'
        self.log.info(text)

        for param in self.param_list:
            set_param = self.user_node[0].execute_gsguc('set',
                                                        self.constant.GSGUC_SUCCESS_MSG,
                                                        f"{param} = {value_list[self.param_list.index(param)]}")
            self.log.info(set_param)
            self.assertTrue(set_param, '参数设置失败')

        self.log.info('---重启集群使参数生效---')
        restart = self.user_node[0].restart_db_cluster(False)
        self.log.info(restart)
        self.assertTrue(restart)

        self.log.info('---查看参数值修改是否成功---')
        for param in self.param_list:
            value = self.user_node[0].execut_db_sql(f'show {param};')
            res = value.splitlines()[-2].strip() if value.splitlines()[-2].strip() else "''"
            self.assertEqual(res, value_list[self.param_list.index(param)], '参数未修改成功')

        text = '-----step3:主备节点查看系统视图pg_total_memory_detail中DMSDrcContext字段' \
               '是否存在  expect:无相关信息-----'
        self.log.info(text)

        sql1 = f"select * from {self.sys_view1} where memorytype='DMSDrcContext';"
        self.log.info(sql1)
        sql2 = f"select * from {self.sys_view2} where memorytype='DMSDrcContext';"
        self.log.info(sql2)

        for node in self.user_node:
            res1 = node.execut_db_sql(sql1)
            self.log.info(res1)
            self.assertIn('(0 rows)', res1, '存在异常信息')

        for node in self.user_node:
            res2 = node.execut_db_sql(sql2)
            self.log.info(res2)
            self.assertIn('(0 rows)', res2, '存在异常信息')

        text = '-----step4:主备节点查看系统表gs_shared_memory_detail中DMSDrcContext字段' \
               '是否存在  expect:存在DMSDrcContext相关字段及信息-----'
        self.log.info(text)

        sql3 = f"select * from {self.sys_view3} where contextname='DMSDrcContext';"
        self.log.info(sql3)
        sql4 = f"select * from {self.sys_view4} where contextname = 'DMSDrcContext';"
        self.log.info(sql4)

        for node in self.user_node:
            res3 = node.execut_db_sql(sql3)
            self.log.info(res3)
            self.assertIn('DMSDrcContext', res3.splitlines()[-2], '存在异常信息')

        for node in self.user_node:
            res4 = node.execut_db_sql(sql4)
            self.log.info(res4)
            self.assertIn('DMSDrcContext', res4.splitlines()[-2], '存在异常信息')

        text = '-----step5:主备节点查看系统表gs_thread_memory_context中DMSMemContext字段' \
               '是否存在  expect:存在DMSMemContext相关字段及信息-----'
        self.log.info(text)

        sql5 = f"select * from {self.sys_view5} where contextname = 'DMSMemContext';"
        self.log.info(sql5)
        sql6 = f"select * from {self.sys_view6} where contextname = 'DMSMemContext';"
        self.log.info(sql6)

        for node in self.user_node:
            res5 = node.execut_db_sql(sql5)
            self.log.info(res5)
            self.assertIn('DMSMemContext', res5, '存在异常信息')

            res6 = node.execut_db_sql(sql6)
            self.log.info(res6)
            self.assertIn('DMSMemContext', res6.splitlines()[-2], '存在异常信息')

            rows, _ = self.com.parse_sql_query_res(res6)
            tid1 = rows[0][0].split('.')[-1]
            sql7 = f"select * from {self.sys_view7}({tid1}, 'DMSMemContext');"
            self.log.info(sql7)
            res7 = node.execut_db_sql(sql7)
            self.log.info(res7)
            self.assertIn('ss_dms_callback.cpp', res7, '存在异常信息')

        text = '-----step6:主备节点查看系统表dbe_perf.track_memory_context_detail中' \
               'DMSDrcContext字段是否存在  expect:无相关信息-----'
        self.log.info(text)

        sql8 = f"select * from {self.sys_view8}('DMSDrcContext');"
        self.log.info(sql8)

        for node in self.user_node:
            res8 = node.execut_db_sql(sql8)
            self.log.info(res8)
            self.assertEqual('t', res8.splitlines()[-2].strip(), '存在异常信息')

            res9 = node.execut_db_sql(f"select * from {self.sys_view9};", dbname='postgres')
            self.log.info(res9)
            self.assertIn('(0 rows)', res9, '存在异常信息')

        text = '-----step7:mv掉dn目录，kill掉dn进程,查看集群状态  expect:原主异常，集群内产生新主-----'
        self.log.info(text)

        pid = self.com.get_pid(self.pri_user, 'bin/gaussdb')
        self.log.info(pid)

        mv = self.pri_user.sh(f'mv {macro.DB_INSTANCE_PATH} {macro.DB_INSTANCE_PATH}_bak').result()
        self.log.info(mv)

        kill = self.pri_user.sh(f'kill -9 {pid}').result()
        self.log.info(kill)
        time.sleep(60)
        status = self.user_node[0].exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertNotIn('Normal', status.splitlines()[-1].split('|')[0], '执行失败')
        self.assertTrue('Primary Normal' in status.splitlines()[-1].split('|')[1]
                        or 'Primary Normal' in status.splitlines()[-1].split('|')[-1], '集群状态异常')

        text = '-----step8:新主备节点查看系统视图pg_total_memory_detail中DMSDrcContext字段' \
               '是否存在  expect:无相关信息-----'
        self.log.info(text)

        for node in self.user_node[1:]:
            res1_1 = node.execut_db_sql(sql1)
            self.log.info(res1_1)
            self.assertIn('(0 rows)', res1_1, '存在异常信息')

        for node in self.user_node[1:]:
            res2_1 = node.execut_db_sql(sql2)
            self.log.info(res2_1)
            self.assertIn('(0 rows)', res2_1, '存在异常信息')

        text = '-----step9:新主备节点查看系统表gs_shared_memory_detail中DMSDrcContext字段' \
               '是否存在  expect:存在DMSDrcContext相关字段及信息-----'
        self.log.info(text)

        for node in self.user_node[1:]:
            res3_1 = node.execut_db_sql(sql3)
            self.log.info(res3_1)
            self.assertIn('DMSDrcContext', res3_1.splitlines()[-2], '存在异常信息')

        for node in self.user_node[1:]:
            res4_1 = node.execut_db_sql(sql4)
            self.log.info(res4_1)
            self.assertIn('DMSDrcContext', res4_1.splitlines()[-2], '存在异常信息')

        text = '-----step10:新主备节点查看系统表gs_thread_memory_context中DMSMemContext字段' \
               '是否存在  expect:存在DMSMemContext相关字段及信息-----'
        self.log.info(text)

        for node in self.user_node[1:]:
            res5_1 = node.execut_db_sql(sql5)
            self.log.info(res5_1)
            self.assertIn('DMSMemContext', res5_1, '存在异常信息')

            res6_1 = node.execut_db_sql(sql6)
            self.log.info(res6_1)
            self.assertIn('DMSMemContext', res6_1.splitlines()[-2], '存在异常信息')

            rows, _ = self.com.parse_sql_query_res(res6_1)
            tid2 = rows[0][0].split('.')[-1]
            sql7_1 = f"select * from {self.sys_view7}({tid2},'DMSMemContext');"
            self.log.info(sql7_1)
            res7_1 = node.execut_db_sql(sql7_1)
            self.log.info(res7_1)
            self.assertIn('ss_dms_callback.cpp', res7_1, '存在异常信息')

        text = '-----step11:新主备节点查看系统表dbe_perf.track_memory_context_detail中' \
               'DMSDrcContext字段是否存在  expect:无相关信息-----'
        self.log.info(text)

        for node in self.user_node[1:]:
            res8_1 = node.execut_db_sql(sql8)
            self.log.info(res8_1)
            self.assertEqual('t', res8_1.splitlines()[-2].strip(), '存在异常信息')

            res9_1 = node.execut_db_sql(f"select * from {self.sys_view9};", dbname='postgres')
            self.log.info(res9_1)
            self.assertIn('(0 rows)', res9_1, '存在异常信息')

    def tearDown(self):
        text = '-----step12:恢复初始环境  expect:恢复成功-----'
        self.log.info(text)

        mv_bak = self.pri_user.sh(f'mv {macro.DB_INSTANCE_PATH}_bak {macro.DB_INSTANCE_PATH};'
                                  f'ls {macro.DB_INSTANCE_PATH}').result()
        self.log.info(mv_bak)

        start = self.user_node[0].exec_cm_ctl('start')
        self.log.info(start)

        for param in self.param_list:
            reset_param = self.user_node[0].execute_gsguc('set',
                                                          self.constant.GSGUC_SUCCESS_MSG,
                                                          f'{param} = {self.default_value[self.param_list.index(param)]}')
            self.log.info(reset_param)

        restart = self.user_node[0].restart_db_cluster(False)
        self.log.info(restart)

        restore = self.user_node[0].exec_cm_ctl('switchover', '-a')
        self.log.info(restore)

        status = self.user_node[0].exec_cm_ctl('query', '-Cv')
        self.log.info(status)

        for param in self.param_list:
            reset_value = self.user_node[0].execut_db_sql(f'show {param};')
            self.log.info(reset_value)
            res = reset_value.splitlines()[-2].strip() if reset_value.splitlines()[-2].strip() else "''"
            self.assertEqual(res, self.default_value[self.param_list.index(param)], '参数恢复失败')
        self.assertIn('Primary Normal', status.splitlines()[-1].split('|')[0],
                      '恢复集群初始状态失败')
        self.log.info(f'----{os.path.basename(__file__)} end----')
